[VTD] don't enable device ATS if root port does not support it
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 6 Oct 2009 09:11:14 +0000 (10:11 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 6 Oct 2009 09:11:14 +0000 (10:11 +0100)
Fixed a bug in the code that enables ATS capability on the device even
when root port does not support it.

Signed-off-by: Allen Kay <allen.m.kay@intel.com>
xen/drivers/passthrough/vtd/x86/ats.c

index 8a180d370e177e185bab484c43cff9ee36cb77c2..308a66640df17aba10b7ff66e66caae5b197e14a 100644 (file)
@@ -118,8 +118,10 @@ int enable_ats_device(int seg, int bus, int devfn)
     u16 queue_depth;
     int pos;
 
-    pos = pci_find_ext_capability(seg, bus, devfn, PCI_EXT_CAP_ID_ATS);
+    if ( acpi_find_matched_atsr_unit(bus, devfn) )
+        return 0;
 
+    pos = pci_find_ext_capability(seg, bus, devfn, PCI_EXT_CAP_ID_ATS);
     if ( !pos )
     {
         dprintk(XENLOG_ERR VTDPREFIX, "ats capability not found %x:%x:%x\n",
@@ -135,21 +137,18 @@ int enable_ats_device(int seg, int bus, int devfn)
                             PCI_FUNC(devfn), pos + ATS_REG_CAP);
     queue_depth = value & ATS_QUEUE_DEPTH_MASK;
 
-    /* BUGBUG: add back seg when multi-seg platform support is enabled */
-    value = pci_conf_read16(bus, PCI_SLOT(devfn), PCI_FUNC(devfn), pos + ATS_REG_CTL);
+    value = pci_conf_read16(bus, PCI_SLOT(devfn),
+                            PCI_FUNC(devfn), pos + ATS_REG_CTL);
     value |= ATS_ENABLE;
+    pci_conf_write16(bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+                     pos + ATS_REG_CTL, value);
 
-    /* BUGBUG: add back seg when multi-seg platform support is enabled */
-    pci_conf_write16(bus, PCI_SLOT(devfn), PCI_FUNC(devfn), pos + ATS_REG_CTL, value);
+    pdev = xmalloc(struct pci_ats_dev);
+    pdev->bus = bus;
+    pdev->devfn = devfn;
+    pdev->ats_queue_depth = queue_depth;
+    list_add(&(pdev->list), &ats_devices);
 
-    if ( acpi_find_matched_atsr_unit(bus, devfn) )
-    {
-        pdev = xmalloc(struct pci_ats_dev);
-        pdev->bus = bus;
-        pdev->devfn = devfn;
-        pdev->ats_queue_depth = queue_depth;
-        list_add(&(pdev->list), &ats_devices);
-    }
     return pos;
 }